﻿Перем юТест;

Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт
	
	юТест = ЮнитТестирование;
	СИ = Новый СистемнаяИнформация;
	
	ВсеТесты = Новый Массив;
	
	ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтениеПострочно");
	ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтениеСОграничениемРазмераСтроки");
	ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтениеСНеобычнымРазделителем1");
	ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтениеСНеобычнымРазделителем2");
	ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтениеСНеобычнымРазделителем3");
	ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтениеИзПотока");
	ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтениеПоУмолчаниюПриРазныхРазделителях");
	ВсеТесты.Добавить("ТестДолжен_ПроверитьСовместимостьПоведения");
	ВсеТесты.Добавить("ТестДолжен_ПроверитьНаличиеПараметраМонопольно");
	ВсеТесты.Добавить("ТестДолжен_ПроверитьРаботоспособностьПараметраМонопольно");
	ВсеТесты.Добавить("ТестДолжен_ПроверитьСозданиеЧтенияИзПотока");
	
	Возврат ВсеТесты;
	
КонецФункции

Функция ЭкранироватьПереводыСтрок(Знач Строка)

	Возврат СтрЗаменить(СтрЗаменить(Строка, Символы.ПС, "\n"), Символы.ВК, "\r");

КонецФункции

Процедура ТестДолжен_ПроверитьЧтениеПострочно() Экспорт

	ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");

	З = Новый ЗаписьТекста(ИмяВременногоФайла);
	З.ЗаписатьСтроку("1");
	З.ЗаписатьСтроку("2");
	З.ЗаписатьСтроку("3");

	З.Закрыть();

	Ч = Новый ЧтениеТекста(ИмяВременногоФайла);
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "1", "Чтение строк");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "2", "Чтение строк");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "3", "Чтение строк");
	юТест.ПроверитьРавенство(Ч.ПрочитатьСтроку(), Неопределено, "Чтение строк");
	юТест.ПроверитьРавенство(Ч.ПрочитатьСтроку(), Неопределено, "Чтение строк");

КонецПроцедуры

Процедура ТестДолжен_ПроверитьЧтениеСОграничениемРазмераСтроки() Экспорт

	ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");

	З = Новый ЗаписьТекста(ИмяВременногоФайла);
	З.ЗаписатьСтроку("01234567890123456789"); // 20 символов
	З.ЗаписатьСтроку("01234567890123456789"); // 20 символов

	З.Закрыть();

	Ч = Новый ЧтениеТекста(ИмяВременногоФайла);
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.Прочитать(10)), "0123456789", "Чтение посимвольно");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.Прочитать(8)),  "01234567", "Чтение посимвольно");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.Прочитать(10)), ЭкранироватьПереводыСтрок("89
			|0123456"), "Чтение строк с переводом"
	);

	Ч.Прочитать(); // Читаем до конца файла

	юТест.ПроверитьРавенство(Ч.Прочитать(), Неопределено, "Чтение после конца файла");

КонецПроцедуры

Процедура ТестДолжен_ПроверитьЧтениеСНеобычнымРазделителем1() Экспорт

	ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");

	З = Новый ЗаписьТекста(ИмяВременногоФайла);
	З.ЗаписатьСтроку("123");
	З.ЗаписатьСтроку("123
		|45/6
		|789");

	З.Закрыть();

	Ч = Новый ЧтениеТекста(ИмяВременногоФайла,,,"/");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "123");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "123");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "45");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "6");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "789");
	юТест.ПроверитьРавенство(Ч.Прочитать(), Неопределено, "Чтение после конца файла");

КонецПроцедуры

Процедура ТестДолжен_ПроверитьЧтениеСНеобычнымРазделителем2() Экспорт

	ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");

	З = Новый ЗаписьТекста(ИмяВременногоФайла);
	З.ЗаписатьСтроку("123");
	З.ЗаписатьСтроку("1-2-3
		|45/6
		|789");

	З.Закрыть();

	Ч = Новый ЧтениеТекста(ИмяВременногоФайла,,"-","/");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "123\r\n1");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "2");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "3\r\n45\n6\r\n789\r\n");
	юТест.ПроверитьРавенство(Ч.Прочитать(), Неопределено, "Чтение после конца файла");

КонецПроцедуры

Процедура ТестДолжен_ПроверитьЧтениеСНеобычнымРазделителем3() Экспорт

	ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");

	З = Новый ЗаписьТекста(ИмяВременногоФайла);
	З.ЗаписатьСтроку("123");
	З.ЗаписатьСтроку("1-2-3
		|45/6
		|789");

	З.Закрыть();

	Ч = Новый ЧтениеТекста(ИмяВременногоФайла,,"-","/");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.Прочитать()), "123\r\n1-2-3\r\n45\n6\r\n789\r\n", "Чтение с необычными разделителями файла целиком");

КонецПроцедуры

Процедура ТестДолжен_ПроверитьСовместимостьПоведения() Экспорт

	ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");

	З = Новый ЗаписьТекста(ИмяВременногоФайла);
	З.Записать("123123123" + Символы.ВК + "
		|45/645/645/6" + Символы.ВК + "
		|789789789");

	З.Закрыть();

	// В конструкторе не указываем конвертируемый перевод строк
	Ч = Новый ЧтениеТекста(ИмяВременногоФайла);
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "123123123\r", "\r в конце строки (через конструктор без параметров по-умолчанию)");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "45/645/645/6\r", "\r в конце строки (через конструктор без параметров по-умолчанию)");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "789789789");

	Ч.Закрыть();

	// В конструкторе указываем конвертируемый перевод строк "по-умолчанию"
	Ч = Новый ЧтениеТекста(ИмяВременногоФайла,,,);
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "123123123", "Нет \r в конце строки (через конструктор с параметрами по-умолчанию)");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "", "Пустая строка вместо \r (через конструктор с параметрами по-умолчанию)");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "45/645/645/6", "Нет \r в конце строки (через конструктор с параметрами по-умолчанию)");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "", "Пустая строка вместо \r (через конструктор с параметрами по-умолчанию)");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "789789789");

	Ч.Закрыть();

	// Используем конструктор по-умолчанию и открытие без указания конвертируемого перевода строк
	Ч = Новый ЧтениеТекста;
	Ч.Открыть(ИмяВременногоФайла);
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "123123123\r", "\r в конце строки (через открытие без параметров по-умолчанию)");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "45/645/645/6\r", "\r в конце строки (через открытие без параметров по-умолчанию)");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "789789789");

	Ч.Закрыть();

	// Используем конструктор по-умолчанию и открытие с указанием конвертируемого перевода строк "по-умолчанию"
	Ч = Новый ЧтениеТекста;
	Ч.Открыть(ИмяВременногоФайла,,,);
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "123123123\r", "\r в конце строки (через открытие с параметрами по-умолчанию)");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "45/645/645/6\r", "\r в конце строки (через открытие с параметрами по-умолчанию)");
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), "789789789");

	Ч.Закрыть();

КонецПроцедуры

Процедура ЗаписатьСтрокуТекстаИСравнить(Знач Разделитель, Знач Текст)

	// Запись с указанным разделителем
	ИмяФайла = ПолучитьИмяВременногоФайла("txt");
	З = Новый ЗаписьТекста(ИмяФайла,,,, Разделитель);
	З.Записать(Текст);
	З.Закрыть();

	// Чтение по-умолчанию
	Ч = Новый ЧтениеТекста(ИмяФайла);
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.Прочитать()), ЭкранироватьПереводыСтрок(Текст), "Равенство при записи с " + ЭкранироватьПереводыСтрок(Разделитель));

КонецПроцедуры

Процедура ЗаписатьСтрокуТекстаИСравнитьПострочно(Знач Разделитель, Знач Строка1, Знач Строка2, Знач Строка3)

	// Запись с указанным разделителем
	ИмяФайла = ПолучитьИмяВременногоФайла("txt");
	З = Новый ЗаписьТекста(ИмяФайла,,,, Разделитель);
	З.ЗаписатьСтроку(Строка1);
	З.ЗаписатьСтроку(Строка2);
	З.ЗаписатьСтроку(Строка3);
	З.Закрыть();

	// Чтение по-умолчанию
	Ч = Новый ЧтениеТекста(ИмяФайла);
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), ЭкранироватьПереводыСтрок(Строка1), "Равенство при записи с " + ЭкранироватьПереводыСтрок(Разделитель));
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), ЭкранироватьПереводыСтрок(Строка2), "Равенство при записи с " + ЭкранироватьПереводыСтрок(Разделитель));
	юТест.ПроверитьРавенство(ЭкранироватьПереводыСтрок(Ч.ПрочитатьСтроку()), ЭкранироватьПереводыСтрок(Строка3), "Равенство при записи с " + ЭкранироватьПереводыСтрок(Разделитель));
	юТест.ПроверитьРавенство(Ч.ПрочитатьСтроку(), Неопределено, "Равенство при записи с " + ЭкранироватьПереводыСтрок(Разделитель));

КонецПроцедуры

Процедура ТестДолжен_ПроверитьЧтениеПоУмолчаниюПриРазныхРазделителях() Экспорт

	Текст = "1
		|2
		|3"
	;

	ЗаписатьСтрокуТекстаИСравнить(Символы.ПС, Текст);
	ЗаписатьСтрокуТекстаИСравнить(Символы.ВК + Символы.ПС, Текст);
	// ЗаписатьСтрокуТекстаИСравнить(Символы.ВК, Текст); // с ВК заведомо не сработает - такова 1С

	ЗаписатьСтрокуТекстаИСравнитьПострочно(Символы.ПС, "1", "2", "3");
	ЗаписатьСтрокуТекстаИСравнитьПострочно(Символы.ВК + Символы.ПС, "1", "2", "3");

КонецПроцедуры

Процедура ТестДолжен_ПроверитьНаличиеПараметраМонопольно() Экспорт

	ИмяТестовогоФайла = "testdata/ObjectModule.txt";
	
	Ч = Новый ЧтениеТекста(ИмяТестовогоФайла, КодировкаТекста.UTF8NoBOM,
			Символы.ПС,
			Символы.ПС,
			Истина // Проверяем, что отрабатывает новый параметр конструктора
	);

	Ч.Закрыть();

	Ч = Новый ЧтениеТекста;
	Ч.Открыть(ИмяТестовогоФайла, КодировкаТекста.UTF8NoBOM,
		Символы.ПС,
		Символы.ПС,
		Истина // Проверяем, что отрабатывает новый параметр конструктора
	);

	Ч.Закрыть();

КонецПроцедуры

Функция УдалосьОткрытьИПрочитать(Знач Чтение, Знач ИмяФайла, Знач Монопольно)

	Если Чтение = Неопределено Тогда

		Попытка
			
			Если Монопольно = Неопределено Тогда
				
				// Проверяем конструктор с параметром по-умолчанию
				Чтение = Новый ЧтениеТекста(ИмяФайла);

			Иначе

				// Явно передаём значение в конструктор
				Чтение = Новый ЧтениеТекста(ИмяФайла, , , , Монопольно);
				
			КонецЕсли;

			Чтение.Закрыть();
			Возврат Истина;

		Исключение

			Возврат Ложь;

		КонецПопытки;

	КонецЕсли;

	Попытка
		
		Если Монопольно = Неопределено Тогда

			// Поведение с параметром по-умолчанию
			Чтение.Открыть(ИмяФайла);

		Иначе

			// Поведение с яыно заданным параметром
			Чтение.Открыть(ИмяФайла,,,, Монопольно);

		КонецЕсли;

		Чтение.Закрыть();
		Возврат Истина;

	Исключение

		Возврат Ложь;

	КонецПопытки;

КонецФункции

Процедура ТестДолжен_ПроверитьРаботоспособностьПараметраМонопольно() Экспорт

	ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
	Запись = Новый ЗаписьТекста(ИмяВременногоФайла);

	юТест.ПроверитьИстину(УдалосьОткрытьИПрочитать(, ИмяВременногоФайла, Ложь),
			"Немонопольное чтение через конструктор");
	юТест.ПроверитьЛожь(УдалосьОткрытьИПрочитать(, ИмяВременногоФайла, Истина),
			"Монопольное чтение через конструктор");
	юТест.ПроверитьЛожь(УдалосьОткрытьИПрочитать(, ИмяВременногоФайла, Неопределено),
			"Поведение по-умолчанию через конструктор");


	юТест.ПроверитьИстину(УдалосьОткрытьИПрочитать(Новый ЧтениеТекста, ИмяВременногоФайла, Ложь),
			"Немонопольное чтение через Открыть");
	юТест.ПроверитьЛожь(УдалосьОткрытьИПрочитать(Новый ЧтениеТекста, ИмяВременногоФайла, Истина),
			"Монопольное чтение через Открыть");
	юТест.ПроверитьЛожь(УдалосьОткрытьИПрочитать(Новый ЧтениеТекста, ИмяВременногоФайла, Неопределено),
			"Поведение по-умолчанию через Открыть");

	Запись.Закрыть();

	юТест.ПроверитьИстину(УдалосьОткрытьИПрочитать(, ИмяВременногоФайла, Ложь),
			"Немонопольное чтение через конструктор после закрытия записи");
	юТест.ПроверитьИстину(УдалосьОткрытьИПрочитать(, ИмяВременногоФайла, Истина),
			"Монопольное чтение через конструктор после закрытия записи");
	юТест.ПроверитьИстину(УдалосьОткрытьИПрочитать(, ИмяВременногоФайла, Неопределено),
			"Поведение по-умолчанию через конструктор после закрытия записи");

	юТест.ПроверитьИстину(УдалосьОткрытьИПрочитать(Новый ЧтениеТекста, ИмяВременногоФайла, Ложь),
			"Немонопольное чтение через Открыть после закрытия записи");
	юТест.ПроверитьИстину(УдалосьОткрытьИПрочитать(Новый ЧтениеТекста, ИмяВременногоФайла, Истина),
			"Монопольное чтение через Открыть после закрытия записи");
	юТест.ПроверитьИстину(УдалосьОткрытьИПрочитать(Новый ЧтениеТекста, ИмяВременногоФайла, Неопределено),
			"Поведение по-умолчанию через Открыть после закрытия записи");

КонецПроцедуры

Процедура ТестДолжен_ПроверитьЧтениеИзПотока() Экспорт

	Поток = ПотокВПамятиИзФайла();
	ЧтениеТекста = Новый ЧтениеТекста();
	ЧтениеТекста.Открыть(Поток, "UTF-8");
	Результат = ЧтениеТекста.Прочитать();

	юТест.ПроверитьРавенство("ПРИВЕТ, Я МАКЕТ", Результат);

КонецПроцедуры

Процедура ТестДолжен_ПроверитьСозданиеЧтенияИзПотока() Экспорт
	
	Поток = ПотокВПамятиИзФайла();
	ЧтениеТекста = Новый ЧтениеТекста(Поток, "UTF-8");
	Результат = ЧтениеТекста.Прочитать();
	
	юТест.ПроверитьРавенство("ПРИВЕТ, Я МАКЕТ", Результат);

КонецПроцедуры

Функция ПотокВПамятиИзФайла()

	ДД = Новый ДвоичныеДанные("./templateslib/TemplateData.txt");

	Кодировка = "UTF-8";
	
	ПотокВПамяти = Новый ПотокВПамяти;
		
	Запись = Новый ЗаписьДанных(ПотокВПамяти, Кодировка);
	Запись.Записать(ДД);
	//TODO: Раскоменить после принятия ПР по #928
	//Запись.Закрыть();
	
	ПотокВПамяти.Перейти(0, ПозицияВПотоке.Начало);

	Возврат ПотокВПамяти;

КонецФункции